﻿#pragma once
#include "XyNet/Global.h"

namespace XyNet
{
	/// 异常
	class XYNET_API Exception : public exception
	{
	public:
		typedef function<void(const exception&)> ExceptionHandler;

	public:
		Exception(const string& message, const char* currentFunction = nullptr,
			const char* file = nullptr, long line = 0);
		virtual ~Exception();

		/// 描述
		virtual const char* what() const throw() override;

		/// 处理异常
		static void handleException(const exception& e);
		/// 处理异常（含处理位置）
		static void handleException(const exception& e,
			const char* currentFunction, const char* file, long line);
		/// 默认异常处理器
		static void defaultHandleException(const exception& e);
		/// 设置异常处理器
		static void setExceptionHandler(const ExceptionHandler& handler);

	private:
		/// 信息
		string _message;
		/// 异常处理器
		static ExceptionHandler _exceptionHandler;
	};

	// 包含函数信息的异常，只有使用宏才能获得准确的文件、行、函数信息
#define XYNET_EXCEPTION(message) XyNet::Exception((message), BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)

	// 处理异常，定位处理异常的位置
#define XYNET_HANDLE_EXCEPTION(e) XyNet::Exception::handleException(e, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)

	// 检查条件表达式结果是否为真，如果假则抛出异常
#define XYNET_CHECK(expression) (expression) ? ((void)0) : throw XYNET_EXCEPTION(#expression)

	// 断言
#ifdef _DEBUG
#	define XYNET_ASSERT(expression) assert(expression)
#else
#	define XYNET_ASSERT(expression) ((void)0)
#endif // _DEBUG
}

//////////////////////////////////////////////////////////////////////////

namespace XyNet
{
	extern "C"
	{
		/// 处理异常
		XYNET_API void HandleException(const exception& e);
		/// 设置外部异常处理
		XYNET_API void SetExternalExceptionHandler();
		/// 异常信息栈是否为空
		XYNET_API bool IsExceptionMessageStackEmpty();
		/// 取出顶部异常信息
		XYNET_API string* PopExceptionMessage();
	}
}